package com.yeskery.nut.extend.jdbc;

import java.lang.reflect.Method;
import java.util.Map;

/**
 * 分页SQL Object结果集分裂器
 * @author YESKERY
 * 2024/8/29
 *
 * @param <T> 结果类型
 */
public class PageSqlObjectResultSetSpliterator<T> extends PageSqlResultSetSpliterator<T> {

    /** 结果类型 */
    private final Class<T> clazz;

    /** 列名策略 */
    private final ColumnNameStrategy columnNameStrategy;

    /** 结果集回调接口 */
    private final ResultSetRowCallback<T> callback = rs -> {
        JdbcResultConverter resultConverter = JdbcResultConverter.getInstance();
        T t = resultConverter.createObject(getObjectClass());
        resultConverter.appendObjectFieldFromResultSet(rs, rs.getMetaData(), getSetMethodMap(), t);
        return t;
    };

    /** 获取列名与字段的映射 */
    private Map<String, Method> setMethodMap;

    /**
     * 构建分页SQL结果集分裂器
     * @param clazz 结果类型
     * @param columnNameStrategy 列名策略
     * @param jdbcTemplate JDBC操作模板
     * @param sql sql
     * @param size 每页的条数
     */
    public PageSqlObjectResultSetSpliterator(Class<T> clazz, ColumnNameStrategy columnNameStrategy, JdbcTemplate jdbcTemplate, String sql, int size) {
        super(jdbcTemplate, sql, size, (ResultSetRowCallback<T>) null);
        this.clazz = clazz;
        this.columnNameStrategy = columnNameStrategy;
        setResultSetRowCallback(callback);
    }

    /**
     * 构建分页SQL结果集分裂器
     * @param clazz 结果类型
     * @param columnNameStrategy 列名策略
     * @param jdbcTemplate JDBC操作模板
     * @param sql sql
     * @param params 参数
     * @param size 每页的条数
     */
    public PageSqlObjectResultSetSpliterator(Class<T> clazz, ColumnNameStrategy columnNameStrategy, JdbcTemplate jdbcTemplate, String sql, Object[] params, int size) {
        super(jdbcTemplate, sql, params, size, (ResultSetRowCallback<T>) null);
        this.clazz = clazz;
        this.columnNameStrategy = columnNameStrategy;
        setResultSetRowCallback(callback);
    }

    /**
     * 获取列名与字段的映射
     * @return 列名与字段的映射
     */
    private Map<String, Method> getSetMethodMap() {
        if (setMethodMap == null) {
            setMethodMap = JdbcResultConverter.getInstance().getSetMethodMap(columnNameStrategy, clazz);
        }
        return setMethodMap;
    }

    /**
     * 获取结果类型
     * @return 结果类型
     */
    private Class<T> getObjectClass() {
        return clazz;
    }
}
